Reverse between left and right in a singly linked list#113
Conversation
Adds validation checks for the reverse_between method of the singly linked list class and tests to validate these changes. Additionally adds linting fixes to the code base
|
Caution Review failedThe pull request is closed. WalkthroughRefactors the singly linked list package to re-export node and implementation, adds a new comprehensive Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
datastructures/trees/heaps/binary/min_heap/__init__.py (1)
62-81: Critical: FIXME comment indicates a real bug in index tracking logic.The added FIXME comment correctly identifies a KeyError issue, but the root cause lies in the index swapping logic. Lines 73–79 attempt a double-lookup pattern (
self.idx_of_element[self.idx_of_element[self.heap[idx]]]) which is logically incorrect and causes KeyError when the inner result is not a valid dictionary key.The same flawed pattern appears in
__bubble_down(lines 52–58). After swapping heap elements, the corresponding dictionary entries should be swapped directly—not double-looked-up.Apply this corrected logic to both
__bubble_upand__bubble_down:For
__bubble_up(lines 73–79):( self.idx_of_element[self.heap[parent_idx]], self.idx_of_element[self.heap[idx]], ) = ( - self.idx_of_element[self.idx_of_element[self.heap[idx]]], - self.idx_of_element[self.idx_of_element[self.heap[parent_idx]]], + self.idx_of_element[self.heap[idx]], + self.idx_of_element[self.heap[parent_idx]], )For
__bubble_down(lines 52–58):( self.idx_of_element[self.heap[min_child_index]], self.idx_of_element[self.heap[idx]], ) = ( - self.idx_of_element[self.idx_of_element[self.heap[idx]]], - self.idx_of_element[self.idx_of_element[self.heap[min_child_index]]], + self.idx_of_element[self.heap[idx]], + self.idx_of_element[self.heap[min_child_index]], )Would you like me to help prepare a fix for this issue, or would you prefer to investigate the intended behavior of
idx_of_elementfirst?datastructures/trees/trie/suffix/suffix_tree.py (1)
18-32: Suffix tree best-info logic looks solid; consider guarding empty-tree searchThe
_update_best_infotie-breaking and the wayinsert/search_best_indexpropagate and consumebest_infoare coherent and correctly implement “shortest length, then earliest index wins” along the reversed-word path. Nice separation via a static helper.One minor edge case: if
search_best_indexis called before anyinsert,self.root.best_infowill still be the sentinel (INF_WORD_INFO), so the method will return that sentinel index (currently non‑meaningful). If that’s a realistic call pattern, consider either:
- Returning a sentinel like
-1, or- Raising a specific exception (e.g.,
ValueError("search_best_index on empty SuffixTree")).Also applies to: 56-85
🧹 Nitpick comments (6)
datastructures/trees/trie/suffix/suffix_tree_node.py (1)
7-21: Avoid redundantbest_indexstate or ensure it’s consistently updatedThe node now exposes both:
best_index = -1, andbest_info: WordInfo = INF_WORD_INFO(where the second element already encodes the index),while the docstring talks about “the index of the best word”. In the current code,
SuffixTreeonly usesbest_info, sobest_indexstays at-1and can be misleading if accessed.To keep the API clear and avoid future divergence:
- Either remove
best_indexfor now and rely solely onbest_info[1], or- Wire
best_indexinto the update path (e.g., set it wheneverbest_infochanges ininsert) so it always mirrorsbest_info[1].DIRECTORY.md (2)
229-241: Fix list indentation and spelling for Singly Linked List entries
- Lines 231 and 241 are indented two spaces deeper than their sibling bullets, which triggers
markdownlint(MD007, ul-indent). Consider reducing indentation to match the other items under “Singly Linked List”.- The visible label “Test Singly Linked Revese” (Line 241) has a typo; if you keep the filename
test_singly_linked_revese.pyfor historical reasons, you can still fix the link text to “Reverse” while leaving the URL unchanged.
540-547: Align heap puzzle bullets with markdown list indentation rulesFor the new “Min Cost To Connect Sticks” section:
- Line 546 (
* Min Cost To Connect Sticks) is indented more than its sibling bullets under* Heap; markdownlint expects 2 leading spaces here.- Line 547 (
* [Test Min Cost Connect Sticks]) similarly has 2 extra spaces and should be aligned with other second‑level bullets.Adjusting the indentation will keep the hierarchy consistent and clear both MD007 warnings.
datastructures/linked_lists/singly_linked_list/test_singly_linked_revese.py (2)
10-23: Good edge coverage; consider adding aright > len(list)failure testThe empty-list and
left > rightcases are well covered and align with the currentreverse_betweenvalidation behavior.Given the implementation also explicitly raises when
right > len(self), it would be useful to add a test that assertsValueErrorfor that path as well (for example, a non-empty list withrightone past the length) to lock in that contract.
24-71: Parameterized tests are solid; you can DRY shared cases and add minor refinementsThese parameterized tests give good coverage of typical and non-trivial sublist reversals for both
reverse_betweenandreverse_between_with_dummy, including full-list reversals and interior segments.A few optional improvements:
- One test tuple in the case list is duplicated (the
[103, 7, 10, -9, 105, 67, 31, 63], 1, 8, [...]case appears twice); you can drop the duplicate without losing coverage.- The case lists for
test_reverse_betweenandtest_reverse_between_with_dummyare identical. Consider extracting them into a shared module-level constant (e.g.,REVERSE_BETWEEN_CASES) and reusing in both decorators to keep them in sync.- If you want to fully exercise the new validations, you could also add:
- a case where
left == right(no-op reversal), and- a case where
right > len(list)that assertsValueErrorfor both implementations.Also applies to: 73-120
datastructures/linked_lists/singly_linked_list/single_linked_list.py (1)
92-95: Stubbed methods should either be implemented or fail loudlySeveral methods are present but unimplemented:
insert_before_node(Lines 92-95)display_backwardanddisplay_forward(Lines 523-528)remove_tail(Lines 976-977)pairs_with_sum(Lines 1119-1120)Right now they silently do nothing (or return
None), which can make debugging difficult if they’re accidentally called.Consider either:
- Implementing them, or
- Raising
NotImplementedErrorwith a short message so misuse is obvious.For example:
def insert_before_node(self, next_key: Any, data: T): - - pass + raise NotImplementedError("insert_before_node is not implemented yet")Same pattern can be applied to the others until you’re ready to add full implementations.
Also applies to: 523-528, 976-977, 1119-1120
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
DIRECTORY.md(3 hunks)datastructures/linked_lists/singly_linked_list/__init__.py(1 hunks)datastructures/linked_lists/singly_linked_list/single_linked_list.py(1 hunks)datastructures/linked_lists/singly_linked_list/test_singly_linked_revese.py(1 hunks)datastructures/trees/heaps/binary/min_heap/__init__.py(1 hunks)datastructures/trees/heaps/node.py(1 hunks)datastructures/trees/trie/suffix/suffix_tree.py(1 hunks)datastructures/trees/trie/suffix/suffix_tree_node.py(2 hunks)datastructures/trees/trie/suffix/types.py(1 hunks)puzzles/heap/min_cost_to_connect_sticks/test_min_cost_connect_sticks.py(5 hunks)pystrings/memesorting/__init__.py(0 hunks)
💤 Files with no reviewable changes (1)
- pystrings/memesorting/init.py
🧰 Additional context used
🧬 Code graph analysis (3)
datastructures/linked_lists/singly_linked_list/test_singly_linked_revese.py (1)
datastructures/linked_lists/singly_linked_list/single_linked_list.py (2)
reverse_between(368-431)reverse_between_with_dummy(433-492)
datastructures/linked_lists/singly_linked_list/single_linked_list.py (2)
datastructures/linked_lists/singly_linked_list/node.py (1)
SingleNode(4-10)datastructures/linked_lists/exceptions/__init__.py (1)
EmptyLinkedList(8-12)
datastructures/linked_lists/singly_linked_list/__init__.py (2)
datastructures/linked_lists/singly_linked_list/node.py (1)
SingleNode(4-10)datastructures/linked_lists/singly_linked_list/single_linked_list.py (1)
SinglyLinkedList(9-1120)
🪛 markdownlint-cli2 (0.18.1)
DIRECTORY.md
231-231: Unordered list indentation
Expected: 4; Actual: 6
(MD007, ul-indent)
241-241: Unordered list indentation
Expected: 4; Actual: 6
(MD007, ul-indent)
546-546: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
547-547: Unordered list indentation
Expected: 4; Actual: 6
(MD007, ul-indent)
🔇 Additional comments (3)
datastructures/trees/heaps/node.py (1)
19-35: LGTM!The type annotation updates maintain consistency and correctness. All comparison methods now use double-quoted forward references uniformly.
puzzles/heap/min_cost_to_connect_sticks/test_min_cost_connect_sticks.py (1)
6-117: Stylistic-only changes; test behavior unchangedThe updates here are purely formatting around list literals and the
__main__block; the test data and assertions are unchanged, so test behavior remains identical.datastructures/linked_lists/singly_linked_list/__init__.py (1)
1-7: Re-export layout for SinglyLinkedList looks goodRe-exporting
SingleNodeandSinglyLinkedListfrom their dedicated modules and exposing them via__all__provides a clean, stable package-level API fordatastructures.linked_lists.singly_linked_list.
Describe your change:
Adds an additional algorithmic approach to reverse between left and right in a singly linked list as well as additional tests and validation logic to the already existing algorithm
Checklist:
Fixes: #{$ISSUE_NO}.Summary by CodeRabbit
New Features
Tests
Documentation
Style
✏️ Tip: You can customize this high-level summary in your review settings.